package br.ufrj.dcc.xml.dynamicintervals.encoding;
/**
 * @author Alexandre Oliveira
 * This classes is a Sax Event Handler that encodes XML 
 * into the Internal Encoding as described in "A Comprehensive XQuery to SQL Translation
 * using Dynamic Interval Encoding", page 4, Definition 3.1. 
 */
import java.util.Stack;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

import br.ufrj.dcc.xml.dynamicintervals.vo.Item;

public abstract class SaxEncoder extends DefaultHandler {

	private Stack<Item> stack = new Stack<Item>();

	private int counter = 0;

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		Item dii = new Item();
		dii.setType( Item.ELEMENT );
		dii.setData( qName );
		dii.setL( counter++ );
		
		stack.push(dii);
		
		for (int i=0; i<attributes.getLength(); ++i) {
			Item att = new Item();
			att.setType( Item.ATTRIBUTE );
			att.setData( attributes.getQName(i) );
			att.setL( counter++ );
			Item attData = new Item();
			attData.setType( Item.ATTRIBUTEVALUE );
			attData.setData( attributes.getValue(i) );
			attData.setL( counter++ );
			attData.setR( counter++ );
			att.setR( counter++ );
			itemGenerated(att);
			itemGenerated(attData);
		}
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		Item dii = stack.pop();
		dii.setR( counter++ );
		itemGenerated(dii);		
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		Item dii = new Item();
		dii.setType( Item.DATA );
		String text = new String(ch,start,length);

		dii.setData( text );
		dii.setL( counter++ );
		dii.setR( counter++ );
		itemGenerated(dii);
	}

	@Override
	public void processingInstruction(String target, String data) throws SAXException {
		Item pi = new Item();
		pi.setType( Item.PROCESSINGINSTRUCTION );
		pi.setL( counter++ );
		pi.setR( counter++ );
		pi.setData( target + " " + data );
		itemGenerated(pi);
	}
	
	@Override
	public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
		characters(ch, start, length);
	}
	
	
	
	
	
	
	/**
	 * @return The list of Items that represents the encoded XML 
	 */

	public abstract void itemGenerated( Item item ) throws SAXException;

	@Override
	public void error(SAXParseException e) throws SAXException {
		throw e;
	}

	@Override
	public void fatalError(SAXParseException e) throws SAXException {
		throw e;
	}

	@Override
	public void warning(SAXParseException e) throws SAXException {
		super.warning(e);
	}
}
